#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

using namespace std;

template <class T>          //类模板就
class Stack
{
    private:
        vector<T> m_elems;  //元素
    
    public:
        void push(T const&); //入栈 -- 引入指针引用
        void pop();          //出栈
        T top() const;       //返回顶值
        bool empty() const  //判空
        {
            return m_elems.empty();
        }
};

template <class T>
void Stack<T>::push(T const& elem)
{
    m_elems.push_back(elem);    //元素压入栈
}

template <class T>
void Stack<T>::pop()
{
    if(empty()){                //判空
        throw out_of_range("Stack<T> :: pop(): empty stack ");
    }
    m_elems.pop_back();         //尾元素弹出栈
}

template <class T>
T Stack<T>::top() const
{
    if(empty()){                //判空
        throw out_of_range("Stack<T> :: pop(): empty stack ");
    }
    return m_elems.back();
};

int main()
{
    try{
        Stack<int> iStack;      //int栈
        Stack<string> sStack;   //string栈

        iStack.push(7);
        cout << iStack.top() << endl;

        sStack.push("Hello World");
        cout << sStack.top() << endl;

        cout << iStack.empty() << endl;
        iStack.pop();
        cout << iStack.empty() << endl;
        //空栈pop
        iStack.pop();
        return 0;
    }
    catch(exception const& e){
        cerr << "Exception: " << e.what() << endl;
        return -1;
    }
    
};